package com.xiaoxu.privatechat.controller.home;

import com.xiaoxu.privatechat.bean.CodeMsg;
import com.xiaoxu.privatechat.bean.PageBean;
import com.xiaoxu.privatechat.bean.Result;
import com.xiaoxu.privatechat.bean.WebSocketMsg;
import com.xiaoxu.privatechat.constant.SessionConstant;
import com.xiaoxu.privatechat.entity.common.Account;
import com.xiaoxu.privatechat.entity.common.Friend;
import com.xiaoxu.privatechat.entity.home.FriendRequest;
import com.xiaoxu.privatechat.server.home.WebSocket;
import com.xiaoxu.privatechat.service.admin.OperaterLogService;
import com.xiaoxu.privatechat.service.common.AccountService;
import com.xiaoxu.privatechat.service.common.FriendService;
import com.xiaoxu.privatechat.service.home.FriendRequestService;
import com.xiaoxu.privatechat.util.SessionUtil;
import com.xiaoxu.privatechat.util.StringUtil;
import com.xiaoxu.privatechat.util.ValidateEntityUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author xiaoxu
 * @description 前台首页控制器
 * @date 2023/2/13
 */
@RequestMapping("/home/account")
@Controller
public class HomeAccountController {

    @Resource
    private AccountService accountService;

    @Resource
    private FriendRequestService friendRequestService;

    @Resource
    private FriendService friendService;

    @Resource
    private OperaterLogService operaterLogService;

    private final Logger log = LoggerFactory.getLogger(HomeAccountController.class);

    /**
     * @return String
     * @description 用户中心主页
     */
    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public String index() {
        return "home/account/index";
    }

    /**
     * @param model 模型
     * @return String
     * @description 好友列表
     */
    @RequestMapping(value = "/friend_list")
    public String friendRequestList(Model model, @RequestParam(name = "from", defaultValue = "0") Integer from) {
        Account onlineAccount = (Account) SessionUtil.get(SessionConstant.SESSION_ACCOUNT_LOGIN_KEY);
        //防止数据库session失效，重新查询
        List<Friend> friendList = friendService.findMyFriendList(Objects.requireNonNull(onlineAccount).getId());
        List<Friend> result = new ArrayList<>();
        for (Friend friend : friendList) {
            if (friend.getFriendAccount().getId() == 1) {
                result.add(friend);
            }
        }
        for (Friend friend : friendList) {
            if (friend.getFriendAccount().getId() == 1) {
                continue;
            }
            result.add(friend);
        }
        model.addAttribute("friendList", result);
        model.addAttribute("from", from);
        return "home/account/friend_list";
    }

    /**
     * @param account 用户信息
     * @return Result
     * @description 修改个人信息
     */
    @RequestMapping(value = "/update_user_info", method = RequestMethod.POST)
    @ResponseBody
    public Result<Boolean> updateUserInfo(Account account) {
        if (account == null) {
            return Result.error(CodeMsg.DATA_ERROR);
        }
        Account onlineAccount = (Account) SessionUtil.get(SessionConstant.SESSION_ACCOUNT_LOGIN_KEY);
        if (!StringUtils.isEmpty(account.getPassword())) {
            Objects.requireNonNull(onlineAccount).setPassword(account.getPassword());
        } else {
            account.setPassword(Objects.requireNonNull(onlineAccount).getPassword());
        }
        if (!StringUtils.isEmpty(account.getUsername())) {
            onlineAccount.setUsername(account.getUsername());
        } else {
            account.setUsername(onlineAccount.getUsername());
        }
        //用统一验证实体方法验证是否合法
        CodeMsg validate = ValidateEntityUtil.validate(account);
        if (validate.getCode() != CodeMsg.SUCCESS.getCode()) {
            return Result.error(validate);
        }
        //检查用户名是否重复
        if (accountService.isExistUsername(account.getUsername(), onlineAccount.getId())) {
            return Result.error(CodeMsg.ACCOUNT_USERNAME_EXIST);
        }
        onlineAccount = accountService.find(onlineAccount.getId());
        onlineAccount.setChatStatus(account.getChatStatus());
        onlineAccount.setEmail(account.getEmail());
        onlineAccount.setHeadPic(account.getHeadPic());
        onlineAccount.setInfo(account.getInfo());
        onlineAccount.setUsername(account.getUsername());
        onlineAccount.setBirthday(account.getBirthday());
        onlineAccount.setSex(account.getSex());
        onlineAccount.setMobile(account.getMobile());
        if (!StringUtils.isEmpty(account.getPassword())) {
            onlineAccount.setPassword(account.getPassword());
        }
        if (accountService.save(onlineAccount) == null) {
            return Result.error(CodeMsg.HANDLE_ERROR);
        }
        SessionUtil.set(SessionConstant.SESSION_ACCOUNT_LOGIN_KEY, onlineAccount);
        operaterLogService.add("用戶【" + account.getUsername() + "】于【" + StringUtil.getFormatterDate(new Date(), "yyyy-MM-dd HH:mm:ss") + "】修改個人資訊！");
        log.info("用戶成功修改個人資訊，user = " + onlineAccount.getUsername());
        //此处判断是否设置下线或隐身
        WebSocket webSocket = WebSocket.clients.get(onlineAccount.getId());
        if (!Account.ACOUNT_CHAT_STATUS_ONLINE.equals(account.getChatStatus())) {
            //通知其好友下线
            if (webSocket != null) {
                webSocket.offlineNotice(onlineAccount.getId());
            }
        } else {
            //通知其好友上线
            if (webSocket != null) {
                webSocket.onlineNotice(onlineAccount.getId());
            }
        }
        return Result.success(true);
    }

    /**
     * @param model    模型
     * @param account  用户信息
     * @param pageBean 分页
     * @return String
     * @description 根据用户名搜索
     */
    @RequestMapping(value = "/search_user_list")
    public String search(Model model, Account account, PageBean<Account> pageBean) {
        Account onlineAccount = (Account) SessionUtil.get(SessionConstant.SESSION_ACCOUNT_LOGIN_KEY);
        List<Long> friendIds = getFriends(onlineAccount);
        model.addAttribute("friendIds", friendIds);
        model.addAttribute("title", "用戶蒐索清單");
        model.addAttribute("username", account.getUsername());
        pageBean.setPageSize(999);
        model.addAttribute("pageBean", accountService.findList(account, pageBean));
        return "home/account/search_user_list";
    }

    private List<Long> getFriends(Account onlineAccount) {
        //防止数据库session失效，重新查询
        List<Friend> friendList = friendService.findMyFriendList(Objects.requireNonNull(onlineAccount).getId());
        List<Long> friendIds = new ArrayList<>();
        for (Friend friend : friendList) {
            friendIds.add(friend.getFriendAccount().getId());
        }
        return friendIds;
    }

    /**
     * @param model    模型
     * @param pageBean 分页
     * @return String
     * @description 根据性别搜索所有用户
     */
    @RequestMapping(value = "/search_all_user_list")
    public String searchAll(Model model, PageBean<Account> pageBean) {
        Account onlineAccount = (Account) SessionUtil.get(SessionConstant.SESSION_ACCOUNT_LOGIN_KEY);
        List<Long> friendIds = getFriends(onlineAccount);
        PageBean<Account> result;
        if (Objects.requireNonNull(onlineAccount).getId() == 23 && onlineAccount.getUsername().equals("admin")) {
            result = accountService.findAdminList(pageBean);
        } else {
            result = accountService.findSexList(onlineAccount, pageBean);
        }
        model.addAttribute("friendIds", friendIds);
        model.addAttribute("title", "用戶蒐索清單");
        model.addAttribute("username", onlineAccount.getUsername());
        pageBean.setPageSize(999);
        model.addAttribute("pageBean", result);
        return "home/account/search_user_list";
    }

    /**
     * @param accountIds 请求好友id
     * @param remark     备注
     * @return Result
     * @description 批量发送好友验证
     */
    @RequestMapping(value = "/add_friend_request", method = RequestMethod.POST)
    @ResponseBody
    public Result<Boolean> addFriendRequest(@RequestParam(name = "accountIds") String accountIds, String remark) {
        String[] split = accountIds.split(",");
        Account sender = (Account) SessionUtil.get(SessionConstant.SESSION_ACCOUNT_LOGIN_KEY);
        for (String id : split) {
            //检查发送请求的接受者是否已经是好友
            List<Friend> friendList = friendService.findMyFriendList(Objects.requireNonNull(sender).getId());
            if (isExist(friendList, Long.valueOf(id))) {
                //表示已经存在,跳过
                continue;
            }
            Account reciever = accountService.find(Long.valueOf(id));
            FriendRequest findBySenderAndReciever = friendRequestService.findBySenderAndReciever(sender, reciever);
            if (findBySenderAndReciever == null) {
                findBySenderAndReciever = new FriendRequest();
                findBySenderAndReciever.setSender(sender);
                findBySenderAndReciever.setReciever(reciever);
            }
            findBySenderAndReciever.setRemark(remark);
            findBySenderAndReciever.setStatus(FriendRequest.FRIEND_REQUEST_STATUS_AGREE);
            //自动添加好友
            //通过好友，添加到自己的通讯录
            List<Friend> senderFriendList = friendService.findMyFriendList(Objects.requireNonNull(sender).getId());
            addFriend(senderFriendList, sender, reciever);
            //把自己添加到对方通讯录
            List<Friend> recieverFriendList = friendService.findMyFriendList(reciever.getId());
            addFriend(recieverFriendList, reciever, sender);
            friendRequestService.save(findBySenderAndReciever);
        }
        return Result.success(true);
    }


    /**
     * @param friend 好友
     * @return Result
     * @description 更新联系人
     */
    @RequestMapping(value = "/update_friend", method = RequestMethod.POST)
    @ResponseBody
    public Result<Boolean> updateContact(Friend friend) {
        Friend findByAccount = friendService.find(friend.getId());
        findByAccount.setMsgStatus(friend.getMsgStatus());
        if (!StringUtils.isEmpty(friend.getRemark())) {
            findByAccount.setRemark(friend.getRemark());
        }
        findByAccount.setStatus(friend.getStatus());
        if (friendService.save(findByAccount) == null) {
            return Result.error(CodeMsg.HANDLE_ERROR);
        }
        Account onlineAccount = (Account) SessionUtil.get(SessionConstant.SESSION_ACCOUNT_LOGIN_KEY);
        WebSocket webSocket = WebSocket.clients.get(Objects.requireNonNull(onlineAccount).getId());
        if (webSocket != null) {
            webSocket.refreshFriendList(new WebSocketMsg());
        }
        return Result.success(true);
    }

    /**
     * @param friendId 好友id
     * @return Result
     * @description 删除好友
     */
    @RequestMapping(value = "/delete_friend", method = RequestMethod.POST)
    @ResponseBody
    public Result<Boolean> deleteFriend(Long friendId) {
        Account onlineAccount = (Account) SessionUtil.get(SessionConstant.SESSION_ACCOUNT_LOGIN_KEY);
        Friend friend = friendService.find(friendId);
        if (friend != null) {
            if (friend.getAccount().getId().longValue() != Objects.requireNonNull(onlineAccount).getId().longValue()) {
                return Result.error(CodeMsg.ACCOUNT_NO_FRIEND);
            }
            friendService.delete(friendId);
        }
        return Result.success(true);
    }

    /**
     * @param friendList 好友列表
     * @param friend     好友
     * @description 通过好友，添加成为好友
     */
    private void addFriend(List<Friend> friendList, Account myAccount, Account friend) {
        for (Friend f : friendList) {
            if (f.getFriendAccount().getId().longValue() == friend.getId().longValue()) {
                //表示已经是好友，跳过
                return;
            }
        }
        //表示不是好友，需添加成好友
        Friend contacts = new Friend();
        contacts.setAccount(myAccount);
        contacts.setFriendAccount(friend);
        contacts.setRemark(friend.getUsername());
        contacts = friendService.save(contacts);
        friendList.add(contacts);
    }

    /**
     * @param addressBook 好友列表
     * @param accountId   账号id
     * @return boolean
     * @description 判断是否存在与通讯录中
     */
    private boolean isExist(List<Friend> addressBook, Long accountId) {
        for (Friend friend : addressBook) {
            if (friend.getFriendAccount().getId().longValue() == accountId.longValue()) {
                //表示已经是好友，跳过
                return true;
            }
        }
        return false;
    }


}
